package cn.chench.init;

import java.io.File;
import java.lang.reflect.Method;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import cn.chench.mapper.PermissionMapper;
import cn.chench.util.AnnotationUtil;
import cn.chench.util.LoggerUtil;
import cn.chench.util.NullUtil;
import cn.chench.util.ThreadPoolUtil;

/**
 * 自动扫描所有接口，并存储到库
 * 
 * @author chencaihui
 * @datetime 2020年11月9日 上午8:48:05
 */
@Order(100)
@Component
public class PermissionInitStarter implements ApplicationRunner {

	@Autowired
	private PermissionMapper permissionMapper;
	
	@Override
	public void run(ApplicationArguments args) throws Exception {
		String classesPath = ClassUtils.getDefaultClassLoader().getResource("").getPath();
		File root = new File(classesPath);
		final File[] files = root.listFiles();
		if(files!=null){
			ThreadPoolUtil.execute(new Runnable() {
				public void run() {
					this.loadClassesPath(files);
					LoggerUtil.info("权限、接口数据", "初始化成功");
				}
				//解析目录
				private void loadClassesPath(File[] files){
					for (File file : files) {
						if(file.isDirectory()){
							File[] childrenFiles = file.listFiles();
							if(childrenFiles!=null){
								this.loadClassesPath(childrenFiles);
							}
						}else if(file.getName().endsWith(".class")){
							String name = file.getName();
							String[] names = name.split("\\.");
							this.loadRestful(file, names[0]);
						}
					}
				}
				//解析类
				private void loadRestful(File classFile, String fileName){
					String classPath = classFile.getPath();
					String packagePath = classPath.substring(classPath.indexOf("classes"), classPath.lastIndexOf(File.separatorChar));
					packagePath = packagePath.replace("classes", "").replace(String.valueOf(File.separatorChar), ".").substring(1);
					Class<?> classes = AnnotationUtil.getClass(packagePath+"."+fileName);
					if(classes!=null){
						Controller controller = classes.getAnnotation(Controller.class);
						if(controller!=null){
							List<Method> methods = AnnotationUtil.getAllMethods(classes);
							for (Method method : methods) {
								this.savePermission(method);
							}
						}
						RestController restController = classes.getAnnotation(RestController.class);
						if(restController!=null){
							List<Method> methods = AnnotationUtil.getAllMethods(classes);
							for (Method method : methods) {
								this.savePermission(method);
							}
						}
					}
				}
				
				private void savePermission(Method method) {
					RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
					if(requestMapping!=null){
						String name = requestMapping.name();
						String url = requestMapping.value()[0];
						Integer count = permissionMapper.checkUrl(url);
						if(count!=null && count>0){
							return;
						}
						RequestMethod[] methods = requestMapping.method();
						String requestMethod = methods.length==1?methods[0].name():"GET;POST";
						if(NullUtil.isNull(name)){
							permissionMapper.add(url, url, requestMethod);
						}else{
							permissionMapper.add(name, url, requestMethod);
						}
						return;
					}
					GetMapping getMapping = method.getAnnotation(GetMapping.class);
					if(getMapping!=null){
						String name = getMapping.name();
						String url = getMapping.value()[0];
						Integer count = permissionMapper.checkUrl(url);
						if(count!=null && count>0){
							return;
						}
						if(NullUtil.isNull(name)){
							permissionMapper.add(url, url, "GET");
						}else{
							permissionMapper.add(name, url, "GET");
						}
						return;
					}
					PostMapping postMapping = method.getAnnotation(PostMapping.class);
					if(postMapping!=null){
						String name = postMapping.name();
						String url = postMapping.value()[0];
						Integer count = permissionMapper.checkUrl(url);
						if(count!=null && count>0){
							return;
						}
						if(NullUtil.isNull(name)){
							permissionMapper.add(url, url, "POST");
						}else{
							permissionMapper.add(name, url, "POST");
						}
						return;
					}
				}
			});
		}
	}
	
}
